home *** CD-ROM | disk | FTP | other *** search
/ PD ROM 1 / PD ROM Volume I - Macintosh Software from BMUG (1988).iso / Stacks / Updates⁄New / TEXAS for BMUG / C progs / TEXAS XFCNs ƒ / getKeyRecordXFCN.1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-12-08  |  3.8 KB  |  195 lines  |  [TEXT/KAHL]

  1. /* HyperCard XFCN that returns information on the index key
  2.  * record number N in the (already opened) key file F ... called as:
  3.  *    getKeyRecord ( N, F)
  4.  * where N is 0-based, and F is a refNum value returned by
  5.  * the XFCN openFile() ....
  6.  *
  7.  * The results are returned as a nice comma-delimited string consisting of:
  8.  *   the number of the first ptr record for this key;
  9.  *   the number of occurrences of the key;
  10.  *   the item's key word, KEY_LENGTH characters long (padded on the right
  11.  *      by trailing blanks as necessary).
  12.  * If there has been a mistake, a null string is returned and the function
  13.  * also emits a beep....
  14.  *
  15.  * Function is stored as XFCN number 300, named "getKeyRecord"....
  16.  *
  17.  * The key file must in the standard ^z browser format as created
  18.  * by qndxr....
  19.  *
  20.  * 871208 ^z
  21.  */
  22.  
  23. #include <MacTypes.h>
  24. #include <FileMgr.h>
  25. #include <OSUtil.h>
  26. #include <HyperXCmd.h>
  27. #include <proto.h>
  28.  
  29. #define KEY_LENGTH  28            /* default choice in building indices */
  30. typedef struct
  31.   {
  32.     char kkey[KEY_LENGTH];
  33.     long ccount;
  34.   }  KEY_REC;
  35.  
  36.  
  37. pascal void main (XCmdBlockPtr paramPtr);
  38. void getKeyRec (KEY_REC *recp, long recNum, int refNum);
  39. int putNum (char *ans, long count);
  40. void complain (XCmdBlockPtr paramPtr);
  41.  
  42.  
  43. pascal void main (paramPtr)
  44.   XCmdBlockPtr paramPtr;
  45.   {
  46.     KEY_REC this_rec, prev_rec;
  47.     int refNum0, i, j;
  48.     long indexRecNum;
  49.     Handle answer;
  50.     
  51.     if (paramPtr->paramCount != 2)
  52.       {
  53.           complain (paramPtr);
  54.           return;
  55.       }
  56.      
  57.     indexRecNum = atol (*(paramPtr->params[0]));
  58.     refNum0 = atol (*(paramPtr->params[1]));
  59.     
  60.     if (indexRecNum < 0 || refNum0 == 0)
  61.       {
  62.           complain (paramPtr);
  63.           return;
  64.       }
  65.     
  66.     answer = NewHandle (256);
  67.     getKeyRec (&prev_rec, indexRecNum - 1, refNum0);
  68.     getKeyRec (&this_rec, indexRecNum, refNum0);
  69.     i = putNum (*answer, prev_rec.ccount);
  70.     *(*answer + i++) = ',';
  71.     j = putNum (*answer + i, this_rec.ccount - prev_rec.ccount);
  72.     i += j;
  73.     *(*answer + i++) = ',';
  74.     for (j = 0; j < KEY_LENGTH; ++j)
  75.         *(*answer + i++) = this_rec.kkey[j];
  76.     *(*answer + i) = '\0';
  77.     
  78.     paramPtr->returnValue = answer;
  79.     return;
  80.   }
  81.  
  82.  
  83. /* function to fetch the requested index record from the file ...
  84.  * note that if an illegal recNum is asked for, it
  85.  * returns 0 for ccount and a blank kkey....
  86.  */
  87.  
  88. void getKeyRec (recp, recordNum, refNum)
  89.   KEY_REC *recp;
  90.   long recordNum;
  91.   int refNum;
  92.   {
  93.     long count;
  94.     int i;
  95.  
  96.     count = sizeof(KEY_REC);
  97.             
  98.     if (recordNum < 0 ||
  99.             SetFPos (refNum, fsFromStart, 
  100.                     recordNum * sizeof(KEY_REC)) != noErr ||
  101.             FSRead (refNum, &count, recp) != noErr)
  102.       {
  103.         for (i = 0; i < KEY_LENGTH; ++i)
  104.             recp->kkey[i] = ' ';
  105.           recp->ccount = 0;
  106.       }
  107.  
  108.     return;
  109.   }
  110.  
  111.  
  112.  
  113. /* function to convert a number into a string and put it into the chosen
  114.  * target place ... returns the number of characters stored ...
  115.  * based on K&R p. 60 example of itoa()....
  116.  */
  117.  
  118. int putNum (ans, num)
  119.   char *ans;
  120.   long num;
  121.   {
  122.     int i, j, s, result;
  123.     
  124.     i = 0;
  125.     s = 1;
  126.     if (num < 0)
  127.       {
  128.         num = -num;
  129.         s = -1;
  130.       }
  131.     
  132.     do
  133.           ans[i++] = num % 10 + '0';
  134.     while ((num /= 10) > 0);
  135.     
  136.     if (s < 0)
  137.         ans[i++] = '-';
  138.     result = i;
  139.     
  140.     for (--i, j = 0; j < i; ++j, --i)
  141.       {
  142.           s = ans[i];
  143.           ans[i] = ans[j];
  144.           ans[j] = s;
  145.       }
  146.  
  147.     return (result);
  148.   }
  149.   
  150.  
  151. /* function to beep and set the return string to null (= "")
  152.  */
  153.  
  154. void complain (paramPtr)
  155.   XCmdBlockPtr paramPtr;
  156.   {
  157.     Handle answer;
  158.     
  159.       SysBeep (10);
  160.     answer = NewHandle (1);
  161.     **answer = '\0';
  162.     paramPtr->returnValue = answer;
  163.     return;
  164.   }
  165.  
  166.  
  167.  
  168. /* function to convert alphabetic string to a long integer ... from LSC
  169.  * library.... simplified to avoid using isspace() & isdigit() ....
  170.  */
  171.  
  172. long atol (s)
  173.   register char *s;
  174.   {
  175.     register char signflag = 0;
  176.     register long r = 0;
  177.  
  178.     while ((*s == ' '))
  179.         s++;
  180.         
  181.     if (*s == '-')
  182.       {
  183.         signflag = 1;
  184.         s++;
  185.       }
  186.     else if (*s == '+')
  187.          s++;
  188.  
  189.     while (*s >= '0' && *s <= '9') 
  190.         r = r * 10 + (*s++ - '0');
  191.     
  192.     return (signflag ? -r : r);
  193. }
  194.  
  195.